package cn.dida.controller;

import cn.dida.model.HttpResponseBodyWrapper;
import cn.dida.model.Pageable;
import cn.dida.model.Product;
import cn.dida.model.UserSession;
import cn.dida.service.DataStatisticsService;
import cn.dida.util.DateUtil;
import cn.dida.util.DateUtils;
import cn.dida.util.ExcelUtil;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSONObject;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by zhangzhiling on 2017/8/11.
 */
@Controller
@RequestMapping("stastics")
public class DataStatisticsController extends BaseController{

    @Autowired
    private DataStatisticsService dataStatistics;


    /**
     * 获取产品列表
     * @param request
     * @return
     * @throws Exception
     */
    @ResponseBody
    @GetMapping("/getProList")
    public Object getProList(HttpServletRequest request) throws Exception {
        UserSession userSession = getUserSession(request);

        List<Product> data = dataStatistics.getProList(userSession.getCompanyId());
        return new HttpResponseBodyWrapper(data);
    }

    /**
     * 月/ 日分布页
     * @param request
     * @return
     * @throws Exception
     */
    @GetMapping("/stats_data")
    public ModelAndView stats_data(HttpServletRequest request) throws Exception {
        Map<String, Object> model = new HashMap<String, Object>();

        SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日");
        Calendar cale = Calendar.getInstance();
        cale.set(Calendar.DAY_OF_MONTH,0);//设置为1号,当前日期既为本月第一天
        String lastDay = format.format(cale.getTime());
//        System.out.println("-----2------lastDay:"+lastDay);

        model.put("lastDay",lastDay);
        return new ModelAndView("stats_data").addAllObjects(model);
    }

    /**
     * 时段分布页
     * @param request
     * @return
     * @throws Exception
     */
    @GetMapping("/stats_time")
    public ModelAndView stats_time(HttpServletRequest request) throws Exception {
        Map<String, Object> model = new HashMap<String, Object>();

        return new ModelAndView("stats_time").addAllObjects(model);
    }
    /**
     * 扫描数据 按月/日/时
     * @param request
     * @param productId
     * @param timeStart
     * @param timeEnd
     * @param type 1、日； 2、月； 3、时
     * @return
     * @throws Exception
     */
    @ResponseBody
    @GetMapping("/dateCount")
    public Object scan_day(HttpServletRequest request,  String productId, Long timeStart, Long timeEnd ,Integer type) throws Exception {
        UserSession userSession = getUserSession(request);


        if (timeStart == null || timeEnd == null) {
            Calendar now = Calendar.getInstance();
            Calendar sevenDaysAgo = Calendar.getInstance();
            sevenDaysAgo.clear();
            sevenDaysAgo.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE));
            sevenDaysAgo.add(Calendar.DATE, -30);

            Calendar today = Calendar.getInstance();
            today.clear();
            today.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE), 23, 59, 59);
            today.set(Calendar.MILLISECOND, 999);

            timeStart = sevenDaysAgo.getTimeInMillis();
            timeEnd = today.getTimeInMillis();
        }

        Map<String,Object> map = new HashedMap();
        List<Map<String,Object>> dateCount = dataStatistics.dataCountDayMonth(userSession.getCompanyId(),productId, timeStart, timeEnd, type);
        List<Map<String,Object>> newOpen = dataStatistics.newOpenCountByDate( userSession.getCompanyId(),productId, timeStart, timeEnd, type);
        map.put("dateCount",dateCount);
        map.put("newOpen",newOpen);
        return new HttpResponseBodyWrapper(map);
    }


//    /**
//     * 新增用户数据
//     * @param request
//     * @param productId
//     * @param timeStart
//     * @param timeEnd
//     * @param type
//     * @return
//     * @throws Exception
//     */
//    @ResponseBody
//    @GetMapping("/new_open_date")
//    public Object new_open_date(HttpServletRequest request, String productId, Long timeStart, Long timeEnd ,Integer type) throws Exception {
//        UserSession userSession = getUserSession(request);
//
//
//        if (timeStart == null || timeEnd == null) {
//            Calendar now = Calendar.getInstance();
//            Calendar sevenDaysAgo = Calendar.getInstance();
//            sevenDaysAgo.clear();
//            sevenDaysAgo.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE));
//            sevenDaysAgo.add(Calendar.DATE, -30);
//            Calendar today = Calendar.getInstance();
//            today.clear();
//            today.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE), 23, 59, 59);
//            today.set(Calendar.MILLISECOND, 999);
//            timeStart = sevenDaysAgo.getTimeInMillis();
//            timeEnd = today.getTimeInMillis();
//        }
//
//        List<Map<String,Object>> data = dataStatistics.newOpenCountByDate( userSession.getCompanyId(),productId, timeStart, timeEnd, type);
//        return new HttpResponseBodyWrapper(data);
//    }

    /**
     * 获取月/日统计列表数据
     * @param request
     * @param productId
     * @param timeStart
     * @param timeEnd
     * @param type  1.按天；2.按月
     * @param page
     * @return
     * @throws Exception
     */
    @ResponseBody
    @PostMapping("/getStatsDateList")
    public Object getStatsDateList(HttpServletRequest request, String productId,
                                   Long timeStart, Long timeEnd ,Integer type,Integer page) throws Exception {
        UserSession userSession = getUserSession(request);

        if (timeStart == null || timeEnd == null) {
            Calendar now = Calendar.getInstance();
            Calendar sevenDaysAgo = Calendar.getInstance();
            sevenDaysAgo.clear();
            sevenDaysAgo.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE));
            sevenDaysAgo.add(Calendar.DATE, -30);
            Calendar today = Calendar.getInstance();
            today.clear();
            today.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE), 23, 59, 59);
            today.set(Calendar.MILLISECOND, 999);
            timeStart = sevenDaysAgo.getTimeInMillis();
            timeEnd = today.getTimeInMillis();
        }

        page = (page == null || page < 1) ? 1 : page;
        Pageable<Map<String,Object>> data = dataStatistics.getStatsDateList( userSession.getCompanyId(),productId, timeStart,
                timeEnd,type,page);
        return new HttpResponseBodyWrapper(data);
    }

    /**
     * 获取月/日统计列表导出数据
     * @param request
     * @param productId
     * @param timeStart
     * @param timeEnd
     * @param type
     * @return
     * @throws Exception
     */
    @GetMapping("/statsDateListExport")
    public String statsDateListExport(HttpServletRequest request,HttpServletResponse response, String productId,
                                      Long timeStart, Long timeEnd ,Integer type) throws Exception {

        UserSession userSession = getUserSession(request);
        if (timeStart == null || timeEnd == null) {
            Calendar now = Calendar.getInstance();
            Calendar sevenDaysAgo = Calendar.getInstance();
            sevenDaysAgo.clear();
            sevenDaysAgo.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE));
            sevenDaysAgo.add(Calendar.DATE, -30);
            Calendar today = Calendar.getInstance();
            today.clear();
            today.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE), 23, 59, 59);
            today.set(Calendar.MILLISECOND, 999);
            timeStart = sevenDaysAgo.getTimeInMillis();
            timeEnd = today.getTimeInMillis();
        }

        List<Map<String,Object>> exportList = dataStatistics.getStatsDateListExport(userSession.getCompanyId(),productId,timeStart,timeEnd,type);

        String fileName = "月/日分布数据导出" + DateUtils.dateToString(Calendar.getInstance().getTime(), "yyyy-MM-dd");

        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(exportList.size());

        Map<String, Object> fmap = null;
        for (Map<String,Object> re : exportList) {
            fmap = new HashMap<String, Object>();
            if(type == 1){
                fmap.put("date", re.get("vdate1"));
            }else{
                fmap.put("date", re.get("year") +"/" + re.get("month"));
            }

            fmap.put("scanCount", re.get("scanCount"));
            fmap.put("psnCount", re.get("psnCount"));
            fmap.put("scanpan", re.get("scanpan"));
            Long openDate = (Long) re.get("psnCount");
            Long scanCount = (Long)re.get("scanCount");
            DecimalFormat  df = new DecimalFormat("######0.00");
            if(openDate != 0){
                fmap.put("aevScan", df.format((double)scanCount/openDate));
            }else{
                fmap.put("aevScan", re.get("scanCount"));
            }

            fmap.put("history_scan_total", re.get("history_scan_total"));
            fmap.put("redCount", re.get("redCount"));
            fmap.put("entityCount", re.get("entityCount"));

            list.add(fmap);
        }

        String columnNames[] = {"时间", "扫码量", "用户量", "新增用户","人均扫码次数","累计扫码量","红包中奖量" ,"实物中奖量"};//列名
        String keys[] = {"date", "scanCount", "psnCount","scanpan","aevScan","history_scan_total","redCount","entityCount"};//map中的key
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            ExcelUtil.createWorkBook(list, keys, columnNames).write(os);
        } catch (IOException e) {
            e.printStackTrace();
        }
        byte[] content = os.toByteArray();
        InputStream is = new ByteArrayInputStream(content);
        // 设置response参数，可以打开下载页面
        response.reset();
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName + ".xls").getBytes(), "iso-8859-1"));
        ServletOutputStream out = response.getOutputStream();
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(is);
            bos = new BufferedOutputStream(out);
            byte[] buff = new byte[2048];
            int bytesRead;
            // Simple read/write loop.
            while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                bos.write(buff, 0, bytesRead);
                bos.flush();
            }
        } catch (final IOException e) {
            throw e;
        } finally {
            if (bis != null)
                bis.close();
            if (bos != null)
                bos.close();
        }

        return null;
    }

    /**
     * 点击区域分布
     * @param request
     * @return
     * @throws Exception
     */
    @GetMapping("/AreaData")
    public ModelAndView selectedProduct(HttpServletRequest request) throws Exception {
        Map<String, Object> model = new HashMap<String, Object>();


        return new ModelAndView("area").addAllObjects(model);
    }

    /**
     * 区域分布，柱形图数据
     * @param request
     * @param productId
     * @return
     * @throws Exception
     */
    @ResponseBody
    @GetMapping("/getAreaData")
    public Object getAreaData(HttpServletRequest request,  String productId) throws Exception {
        UserSession userSession = getUserSession(request);

        Long s= DateUtil.getLongTime("2017/08/31 00:00:00");
        List data = dataStatistics.getAreaData( userSession.getCompanyId(),productId,s);
        return new HttpResponseBodyWrapper(data);
    }

    /**
     * 区域分布列表数据
     * @param request
     * @param productId
     * @param page
     * @return
     * @throws Exception
     */
    @ResponseBody
    @PostMapping("/getAreaDataDetail")
    public Object getAreaDataDetail(HttpServletRequest request,  String productId,Integer page) throws Exception {
        UserSession userSession = getUserSession(request);

        page = (page == null || page < 1) ? 1 : page;

        Long s= DateUtil.getLongTime("2017/08/31 00:00:00");
        Pageable<Map<String,Object>> data = dataStatistics.getAreaDataDetail( userSession.getCompanyId(),productId,page,s);
        return new HttpResponseBodyWrapper(data);
    }

    /**
     * 区域分布列表数据导出
     * @param request
     * @param response
     * @param productId
     * @return
     * @throws Exception
     */
    @GetMapping("/areaExport")
    public String areaExport(HttpServletRequest request,HttpServletResponse response, String productId) throws Exception {



        UserSession userSession = getUserSession(request);
        Long s= DateUtil.getLongTime("2017/08/31 00:00:00");

        List<Map<String,Object>> exportList = dataStatistics.getAreaDataDetailExport(userSession.getCompanyId(),productId,s);

        String fileName = "区域分布数据导出" + DateUtils.dateToString(Calendar.getInstance().getTime(), "yyyy-MM-dd");

        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(exportList.size());

        Map<String, Object> fmap = null;
        for (Map<String,Object> re : exportList) {
            fmap = new HashMap<String, Object>();
            String str = (String)re.get("poi_city");
            if(str.trim().length() == 0){
                fmap.put("poi_city", "未提供");
            }else{
                fmap.put("poi_city", str);
            }

            fmap.put("scanData", re.get("scanData"));
            fmap.put("openDate", re.get("openDate"));
            Long openDate = (Long) re.get("openDate");
            Long scanData =(Long)re.get("scanData");
            DecimalFormat  df = new DecimalFormat("######0.00");
            if(openDate !=0){
                fmap.put("aevScan",df.format((double)scanData/openDate));
            }else{
                fmap.put("aevScan", scanData);
            }

            fmap.put("prizeData", re.get("prizeData"));
            fmap.put("redData", re.get("redData"));
            fmap.put("entityData", (Long)re.get("prizeData")-(Long)re.get("redData"));

            list.add(fmap);
        }

        String columnNames[] = {"区域", "扫码量", "用户量", "人均扫码量","中奖量","红包中奖量" ,"实物中奖量"};//列名
        String keys[] = {"poi_city", "scanData", "openDate","aevScan","prizeData","redData","entityData"};//map中的key
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            ExcelUtil.createWorkBook(list, keys, columnNames).write(os);
        } catch (IOException e) {
            e.printStackTrace();
        }
        byte[] content = os.toByteArray();
        InputStream is = new ByteArrayInputStream(content);
        // 设置response参数，可以打开下载页面
        response.reset();
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName + ".xls").getBytes(), "iso-8859-1"));
        ServletOutputStream out = response.getOutputStream();
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(is);
            bos = new BufferedOutputStream(out);
            byte[] buff = new byte[2048];
            int bytesRead;
            // Simple read/write loop.
            while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                bos.write(buff, 0, bytesRead);
                bos.flush();
            }
        } catch (final IOException e) {
            throw e;
        } finally {
            if (bis != null)
                bis.close();
            if (bos != null)
                bos.close();
        }

        return null;
    }

    
    /**
     * 时段分布 获取x轴y轴展示数据
     * @author kelan
     * @date 2017年8月16日
     * @param request
     * @return
     * @throws Exception
     */
    @ResponseBody
    @GetMapping("/getxAxisyAxisData")
    public Object getxAxisyAxisData(HttpServletRequest request, String productId, Long timeStart, Long timeEnd) throws Exception {
    	 UserSession userSession = getUserSession(request);
         if (timeStart == null || timeEnd == null) {
             Calendar now = Calendar.getInstance();
             Calendar sevenDaysAgo = Calendar.getInstance();
             sevenDaysAgo.clear();
             sevenDaysAgo.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE));
             sevenDaysAgo.add(Calendar.DATE, -30);

             Calendar today = Calendar.getInstance();
             today.clear();
             today.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE), 23, 59, 59);
             today.set(Calendar.MILLISECOND, 999);

             timeStart = sevenDaysAgo.getTimeInMillis();
             timeEnd = today.getTimeInMillis();
         }
        List<Map<String,Object>> scanOpenCountdata = dataStatistics.dataCountByHour(userSession.getCompanyId(),productId, timeStart, timeEnd);
        List<Map<String, Object>> data = dataStatistics.getxAxisTime();
        List<String> list = new ArrayList<String>();
        for(Map<String, Object> map : data){
        	list.add(map.get("xtime").toString());
        }
        List<String> scanCountlist = new ArrayList<String>();
        List<String> openCountlist = new ArrayList<String>();
        for(Map<String, Object> map : scanOpenCountdata){
        	scanCountlist.add(map.get("SCANCOUNT").toString());
            openCountlist.add(map.get("scanpsn").toString());
        }

        JSONObject retjs = new JSONObject();
        retjs.put("xAxisData", list);
        retjs.put("scanNum", scanCountlist);
        retjs.put("userNum", openCountlist);
        return new HttpResponseBodyWrapper(retjs);
    }
    
    /**
     * 时段分布列表数据
     * @param request
     * @param productId
     * @param page
     * @return
     * @throws Exception
     */
    @ResponseBody
    @PostMapping("/getlistDataByHour")
    public Object getlistDataByHour(HttpServletRequest request, String productId, Long timeStart, Long timeEnd,Integer page) throws Exception {
        UserSession userSession = getUserSession(request);

        page = (page == null || page < 1) ? 1 : page;
        if (timeStart == null || timeEnd == null) {
            Calendar now = Calendar.getInstance();
            Calendar sevenDaysAgo = Calendar.getInstance();
            sevenDaysAgo.clear();
            sevenDaysAgo.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE));
            sevenDaysAgo.add(Calendar.DATE, -30);

            Calendar today = Calendar.getInstance();
            today.clear();
            today.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE), 23, 59, 59);
            today.set(Calendar.MILLISECOND, 999);

            timeStart = sevenDaysAgo.getTimeInMillis();
            timeEnd = today.getTimeInMillis();
        }
        Pageable<Map<String,Object>> data = dataStatistics.getlistDataByHour(userSession.getCompanyId(), productId, timeStart, timeEnd,page);
        return new HttpResponseBodyWrapper(data);
    }
    
    /**
     * 时区分布数据导出
     * @author kelan
     * @date 2017年8月17日
     * @param request
     * @param response
     * @param productId
     * @param timeStart
     * @param timeEnd
     * @return
     * @throws Exception
     */
    @GetMapping("/DataByHourExport")
    public String DataByHourExport(HttpServletRequest request,HttpServletResponse response,String productId, Long timeStart, Long timeEnd) throws Exception {
    	UserSession userSession = getUserSession(request);
    	if (timeStart == null || timeEnd == null) {
            Calendar now = Calendar.getInstance();
            Calendar sevenDaysAgo = Calendar.getInstance();
            sevenDaysAgo.clear();
            sevenDaysAgo.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE));
            sevenDaysAgo.add(Calendar.DATE, -30);

            Calendar today = Calendar.getInstance();
            today.clear();
            today.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE), 23, 59, 59);
            today.set(Calendar.MILLISECOND, 999);

            timeStart = sevenDaysAgo.getTimeInMillis();
            timeEnd = today.getTimeInMillis();
        }
    	
        List<Map<String,Object>> exportList = dataStatistics.getlistDataByHourExport(userSession.getCompanyId(), productId, timeStart, timeEnd);
        System.out.println(exportList.toString());
        String fileName = "时区分布数据导出" + DateUtils.dateToString(Calendar.getInstance().getTime(), "yyyy-MM-dd");

        String columnNames[] = {"时段", "扫码量", "用户量", "中奖总量","红包中奖量","实物中奖量"};//列名
        String keys[] = {"xtime", "SCANCOUNT", "scanpsn","WINCOUNT","REDPACKCOUNT","ENTITYCOUNT"};//map中的key
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            ExcelUtil.createWorkBook(exportList, keys, columnNames).write(os);
        } catch (IOException e) {
            e.printStackTrace();
        }
        byte[] content = os.toByteArray();
        InputStream is = new ByteArrayInputStream(content);
        // 设置response参数，可以打开下载页面
        response.reset();
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName + ".xls").getBytes(), "iso-8859-1"));
        ServletOutputStream out = response.getOutputStream();
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(is);
            bos = new BufferedOutputStream(out); 
            byte[] buff = new byte[2048];
            int bytesRead;
            // Simple read/write loop.
            while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                bos.write(buff, 0, bytesRead);
                bos.flush();
            }
        } catch (final IOException e) {
            throw e;
        } finally {
            if (bis != null)
                bis.close();
            if (bos != null)
                bos.close();
        }
        return null;
    }

}
